package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"github.com/alibaba/sentinel-golang/util"
	"log"
	"sync/atomic"
	"time"
)

func main() {
	err := sentinel.InitDefault()
	if err != nil {
		log.Fatalf("初始化sentinel失败,err:%v", err)
	}
	_, err = flow.LoadRules([]*flow.Rule{
		{
			Resource:               "warm-up-test",
			TokenCalculateStrategy: flow.WarmUp,
			ControlBehavior:        flow.Reject,
			Threshold:              1000,
			WarmUpPeriodSec:        10,
			StatIntervalInMs:       1000,
		},
	})
	if err != nil {
		log.Fatalf("加载规则失败,err:%v", err)
	}

	var globalTotal int32
	var passTotal int32
	var blockTotal int32
	ch := make(chan struct{})

	for i := 0; i < 3; i++ {
		go func() {
			for {
				atomic.AddInt32(&globalTotal, 1)
				entry, blockError := sentinel.Entry("warm-up-test", sentinel.WithTrafficType(base.Inbound))
				if blockError != nil {
					atomic.AddInt32(&blockTotal, 1)
				} else {
					atomic.AddInt32(&passTotal, 1)
					entry.Exit()
				}
				time.Sleep(time.Millisecond * 1)
			}
		}()
	}
	go func() {
		var (
			oldTotal, oldPass, oldBlock int32
		)
		for {
			time.Sleep(1 * time.Second)
			glTotal := atomic.LoadInt32(&globalTotal)
			oneSecondTotal := glTotal - oldTotal
			oldTotal = glTotal

			globalPass := atomic.LoadInt32(&passTotal)
			oneSecondPass := globalPass - oldPass
			oldPass = globalPass

			globalBlock := atomic.LoadInt32(&blockTotal)
			oneSecondBlock := globalBlock - oldBlock
			oldBlock = globalBlock
			fmt.Println(util.CurrentTimeMillis()/1000, "total:", oneSecondTotal, " pass:", oneSecondPass, " block:", oneSecondBlock)
		}
	}()
	<-ch
}
